home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / c / indents.zip / parse.c < prev    next >
C/C++ Source or Header  |  1993-05-30  |  11KB  |  309 lines

  1. /**
  2.  * Copyright (c) 1985 Sun Microsystems, Inc.
  3.  * Copyright (c) 1980 The Regents of the University of California.
  4.  * Copyright (c) 1976 Board of Trustees of the University of Illinois.
  5.  * All rights reserved.
  6.  *
  7.  * Redistribution and use in source and binary forms are permitted provided
  8.  * that the above copyright notice and this paragraph are duplicated in all
  9.  * such forms and that any documentation, advertising materials, and other
  10.  * materials related to such distribution and use acknowledge that the
  11.  * software was developed by the University of California, Berkeley, the
  12.  * University of Illinois, Urbana, and Sun Microsystems, Inc.  The name of
  13.  * either University or Sun Microsystems may not be used to endorse or
  14.  * promote products derived from this software without specific prior written
  15.  * permission. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
  16.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES
  17.  * OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  18.  */
  19.  
  20. #include "globals.h"
  21. #include "codes.h"
  22.  
  23. #ifndef lint
  24. # ifndef ANSIC
  25. static char     sccsid[] = "@(#)parse.c    5.8 (Berkeley) 92/06/15";
  26. # endif         /* ANSIC */
  27. #endif          /* not lint */
  28.  
  29.  
  30. #ifdef ANSIC
  31. static void     reduce(void);
  32. void            parse(int tk)
  33. #else           /* ANSIC */
  34. parse(tk)
  35.     int             tk;         /* the code for the construct scanned */
  36. #endif          /* ANSIC */
  37. {
  38.     int             i;
  39. #ifdef debug
  40.     printf("%2d - %s\n", tk, token);
  41. #endif          /* debug */
  42.  
  43.     while (ps.p_stack[ps.tos] == ifhead && tk != elselit) {
  44.         /* true if we have an if without an else */
  45.         ps.p_stack[ps.tos] = stmt;  /* apply the if(..) stmt ::= stmt
  46.                                      * reduction */
  47.         reduce();               /* see if this allows any reduction */
  48.     }
  49.  
  50.     switch (tk) {               /* go on and figure out what to do with the
  51.                                  * input */
  52.  
  53.     case decl:                  /* scanned a declaration word */
  54.         ps.search_brace = btype_2 && !btype_3;
  55.         /* indicate that following brace should be on same line */
  56.         if (ps.p_stack[ps.tos] != decl) {   /* only put one declaration onto
  57.                                              * stack */
  58.             break_comma = true; /* while in declaration, newline should be
  59.                                  * forced after comma */
  60.             ps.p_stack[++ps.tos] = decl;
  61.             ps.il[ps.tos] = ps.i_l_follow;
  62.  
  63.             if (ps.ljust_decl) {/* only do if we want left justified
  64.                                  * declarations */
  65.                 ps.ind_level = 0;
  66.                 for (i = ps.tos - 1; i > 0; --i)
  67.                     if (ps.p_stack[i] == decl)
  68.                         ++ps.ind_level; /* indentation is number of
  69.                                          * declaration levels deep we are */
  70.                 ps.i_l_follow = ps.ind_level;
  71.             }
  72.         }
  73.         break;
  74.  
  75.     case ifstmt:                /* scanned if (...) */
  76.         if (ps.p_stack[ps.tos] == elsehead && ps.else_if)   /* "else if ..." */
  77.             ps.i_l_follow = ps.il[ps.tos];
  78.     case dolit:                 /* 'do' */
  79.     case forstmt:               /* for (...) */
  80.         ps.p_stack[++ps.tos] = tk;
  81.         ps.il[ps.tos] = ps.ind_level = ps.i_l_follow;
  82.         ++ps.i_l_follow;        /* subsequent statements should be indented 1 */
  83.         ps.search_brace = btype_2 && !btype_3;
  84.         break;
  85.  
  86.     case lbrace:                /* scanned { */
  87.         break_comma = false;    /* don't break comma in an initial list */
  88.         if (ps.p_stack[ps.tos] == stmt || ps.p_stack[ps.tos] == decl
  89.             || ps.p_stack[ps.tos] == stmtl)
  90.             ++ps.i_l_follow;    /* it is a random, isolated stmt group or a
  91.                                  * declaration */
  92.         else {
  93.             if (s_code == e_code) {
  94.                 /* only do this if there is nothing on the line */
  95.                 --ps.ind_level;
  96.                 /* it is a group as part of a while, for, etc. */
  97.                 if (ps.p_stack[ps.tos] == swstmt
  98.                     && ((float) ps.case_indent / (float) ps.ind_size) >= 1
  99.                 && ((float) ps.case_code_indent / (float) ps.ind_size) >= 1)
  100.                     --ps.ind_level;
  101.                 /* for a switch, brace should be two levels out from the code */
  102.             }
  103.         }
  104.  
  105.         ps.p_stack[++ps.tos] = lbrace;
  106.         ps.il[ps.tos] = ps.ind_level;
  107.         ps.p_stack[++ps.tos] = stmt;
  108.         /* allow null stmt between braces */
  109.         ps.il[ps.tos] = ps.i_l_follow;
  110.         break;
  111.  
  112.     case whilestmt:             /* scanned while (...) */
  113.         if (ps.p_stack[ps.tos] == dohead) {
  114.             /* it is matched with do stmt */
  115.             ps.ind_level = ps.i_l_follow = ps.il[ps.tos];
  116.             ps.p_stack[++ps.tos] = whilestmt;
  117.             ps.il[ps.tos] = ps.ind_level = ps.i_l_follow;
  118.         } else {                /* it is a while loop */
  119.             ps.p_stack[++ps.tos] = whilestmt;
  120.             ps.il[ps.tos] = ps.i_l_follow;
  121.             ++ps.i_l_follow;
  122.             ps.search_brace = btype_2 && !btype_3;
  123.         }
  124.  
  125.         break;
  126.  
  127.     case elselit:               /* scanned an else */
  128.  
  129.         if (ps.p_stack[ps.tos] != ifhead)
  130.             diag(1, "Unmatched 'else'");
  131.         else {
  132.             ps.ind_level = ps.il[ps.tos];   /* indentation for else should be
  133.                                              * same as for if */
  134.             ps.i_l_follow = ps.ind_level + 1;   /* everything following
  135.                                                  * should be in 1 level */
  136.             ps.p_stack[ps.tos] = elsehead;
  137.             /* remember if with else */
  138.             ps.search_brace = (btype_2 && !btype_3) | ps.else_if;
  139.         }
  140.         break;
  141.  
  142.     case rbrace:                /* scanned a } */
  143.         /* stack should have <lbrace> <stmt> or <lbrace> <stmtl> */
  144.         if (ps.p_stack[ps.tos - 1] == lbrace) {
  145.             if (btype_3)
  146.                 ps.i_l_follow = ps.il[--ps.tos];
  147.             else
  148.                 ps.ind_level = ps.i_l_follow = ps.il[--ps.tos];
  149.             ps.p_stack[ps.tos] = stmt;
  150.         } else
  151.             diag(1, "Stmt nesting error.");
  152.         break;
  153.  
  154.     case swstmt:                /* had switch (...) */
  155.         ps.p_stack[++ps.tos] = swstmt;
  156.         ps.cstk[ps.tos] = case_ind;
  157.         /* save current case indent level */
  158.         ps.il[ps.tos] = ps.i_l_follow;
  159.         case_ind = ps.i_l_follow + ((float) ps.case_indent / (float) ps.ind_size);
  160.         /* cases should be one level down from switch */
  161.         ps.i_l_follow += ((float) ps.case_indent / (float) ps.ind_size)
  162.             + ((float) ps.case_code_indent / (float) ps.ind_size);
  163.         /* statements should be two levels in */
  164.         ps.search_brace = btype_2 && !btype_3;
  165.         break;
  166.  
  167.     case semicolon:             /* this indicates a simple stmt */
  168.         break_comma = false;    /* turn off flag to break after commas in a
  169.                                  * declaration */
  170.         ps.p_stack[++ps.tos] = stmt;
  171.         ps.il[ps.tos] = ps.ind_level;
  172.         break;
  173.  
  174.     default:                    /* this is an error */
  175.         diag(1, "Unknown code to parser");
  176.         return;
  177.     }                           /* end of switch */
  178.  
  179.     reduce();                   /* see if any reduction can be done */
  180.  
  181. #ifdef debug
  182.     for (i = 1; i <= ps.tos; ++i)
  183.         printf("(%d %d)", ps.p_stack[i], ps.il[i]);
  184.     printf("\n");
  185. #endif          /* debug */
  186.  
  187.     return;
  188. }
  189.  
  190. /**
  191.  * Copyright (C) 1976 by the Board of Trustees of the University of Illinois
  192.  *
  193.  * All rights reserved
  194.  *
  195.  *
  196.  * NAME: reduce
  197.  *
  198.  * FUNCTION: Implements the reduce part of the parsing algorithm
  199.  *
  200.  * ALGORITHM: The following reductions are done.  Reductions are repeated until
  201.  * no more are possible.
  202.  *
  203.  * Old TOS      New TOS <stmt> <stmt>   <stmtl> <stmtl> <stmt>  <stmtl> do
  204.  * <stmt>    "dostmt" if <stmt>    "ifstmt" switch <stmt>    <stmt> decl
  205.  * <stmt>    <stmt> "